import { useState } from "react";
import { parseJson } from "../utils/parseJson";
import { InjectionToken } from "tsyringe";
import dayjs from 'dayjs'
import { formatTime } from "../utils/formatTime";
declare const document: any;
declare const $autox: any;
let autox: any;
export interface StateInit<T> {
    (): T;
}
export function useSetState<T>(init: T | StateInit<T>) {
    let [state, setState] = useState<T>(init)
    return {
        data: state,
        setData: (data: Partial<T>) => {
            state = {
                ...state,
                ...data,
                __time: new Date().getTime()
            }
            setState(state)
        },
        time: () => formatTime((state as any)?.__time)
    }
}
const listeners: Map<InjectionToken<any>, Function> = new Map()
export const webAddListener = (key: string, fn: Function) => {
    listeners.set(key, fn)
}

export const webSend = (key: string, ...args: any[])=>{
    const fn = listeners.get(key)
    if(fn) fn(...args)
}

export function onAutoxJsBridgeReady(cb: Function) {
    document.addEventListener("AutoxJsBridgeReady", () => {
        autox = $autox;
        cb()
    });
}

export async function getConfig(key: string) {
    return webCallHandler({
        type: `ACTION_CONFIG_GET`,
        payload: key
    })
}
export async function getConfigs(key: string[]) {
    return webCallHandler({
        type: `ACTION_CONFIG_GETS`,
        payload: JSON.stringify(key)
    })
}
export async function runCommand(name: InjectionToken<any>, ...args: any[]) {
    const listener = listeners.get(name)
    if(listener) listener(...args);
    return webCallHandler({
        type: `ACTION_RUN_COMMAND`,
        payload: JSON.stringify({ type: name, payload: args })
    })
}
export async function log(payload: any) {
    let data = payload;
    if (typeof payload === 'object') {
        data = JSON.stringify(payload)
    }
    const res = await webCallHandler({
        type: `ACTION_LOG`,
        payload: data
    })
    if (res) {
        return res;
    } else {
        console.log(payload)
    }
}
export interface CallHandler<T = any, R = any> {
    (data: T): Promise<R>;
}
export interface Handler<T = any> {
    (data: T): void;
}
export interface Action {
    type: InjectionToken<string>;
    handler: CallHandler<string, string>
}
export interface CallAction {
    type: InjectionToken<string>;
    payload: string;
}
export async function webCallHandler(action: CallAction) {
    if (!autox) return;
    return new Promise((resolve, reject) => {
        autox.callHandler(action.type, action.payload, (data: string) => {
            resolve(parseJson(data))
        });
    })
}
export function webRegisterHandler(action: Action) {
    if (!autox) return;
    autox.registerHandler(action.type, async (data: string, callBack: (val: string) => void) => {
        const res = await action.handler(data)
        callBack(res)
    });
}
